package com.example.demo.grpc.utils;

import com.example.demo.HeaderReq;
import com.example.demo.Request;
import com.example.demo.Response;
import com.google.protobuf.Message;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.util.JsonFormat;
import io.grpc.*;
import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * 接收和响应日志打印
 * @author wg
 */
@GrpcGlobalServerInterceptor
public class ServerLogInterceptor implements ServerInterceptor {
    private static final Logger log= LoggerFactory.getLogger(ServerLogInterceptor.class);
    public static final int MAX_LENGTH = 10000;

    private String truncateLog(String str){
        if(str.length()> MAX_LENGTH){
            return str.substring(0,MAX_LENGTH)+"...";
        }
        return str;
    }
    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
        ServerCall<ReqT, RespT> listener = new ForwardingServerCall.SimpleForwardingServerCall<>(call) {
            @Override
            public void sendMessage(RespT message) {
                try {
                    Response response = (Response) message;
                    String print = printer().print(MsgParse.parseResBody(response));
                    var r=truncateLog(print);
                    log.info("响应: {} [{}]  =>  {}",response.getHead().getCode(),response.getHead().getMsg(),print);
                } catch (Exception e) {
                    log.error("protobuf转换json失败",e);
                }
                super.sendMessage(message);
            }
        };

        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<>(next.startCall(listener, headers)) {
            @Override
            public void onMessage(ReqT message) {
                try {
                    Request request = (Request) message;
                    if(request.hasHead()){
                        HeaderReq head = request.getHead();
                        MDC.put("traceId",head.getTraceId());
                        MDC.put("traceCode",head.getTraceCode());
                    }
                    String print = printer().print(MsgParse.parseReqBody(request));
                    var r=truncateLog(print);
                    log.info("方法名:{},接收:{}",call.getMethodDescriptor().getFullMethodName(), r);
                } catch (Exception e) {
                    log.error("protobuf转换json失败",e);
                }
                super.onMessage(message);
            }
        };
    }

    private JsonFormat.Printer printer(){
        return JsonFormat.printer().omittingInsignificantWhitespace();
    }
}
